<template>
  <el-dialog id="field_edit" width="80%" :title="header" :visible="isVisible" :show-close="false">
    <el-row :gutter="20">
      <el-col :span="8">
        <el-form label-position="right" label-width="100px" ref="fieldForm" :model="fieldOfBean"
            :rules="rules" @validate="formValidated">
          <el-form-item label="名称" prop="name">
            <el-input v-model="fieldOfBean.name" minlength="1" maxlength="40"/>
          </el-form-item>
          <el-form-item label="数据类型" prop="dataType">
            <el-select v-model="fieldOfBean.dataType">
              <el-option key="VARCHAR" value="VARCHAR" label="字符串"/>
              <el-option key="INT32" value="INT32" label="32位整数"/>
              <el-option key="INT64" value="INT64" label="64位整数"/>
              <el-option key="DECIMAL" value="DECIMAL" label="小数"/>
              <el-option key="UUID" value="UUID" label="UUID"/>
              <el-option key="DATETIME" value="DATETIME" label="日期时间"/>
              <el-option key="DATE" value="DATE" label="日期"/>
              <el-option key="TIME" value="TIME" label="时间"/>
              <el-option key="CLOB" value="CLOB" label="长文本"/>
              <el-option key="BLOB" value="BLOB" label="二进制"/>
            </el-select>
          </el-form-item>
          <el-form-item label="列名" prop="dbColumn">
            <el-input v-model="fieldOfBean.dbColumn" minlength="1" maxlength="40"/>
          </el-form-item>
          <el-form-item :label="precisionOrLengthLabel" v-if="precisionOrLengthLabel" prop="precisionOrLength">
            <el-input-number v-model.number="fieldOfBean.precisionOrLength" :min="1" :step="1" size="small"/>
          </el-form-item>
          <el-form-item label="日期时间格式" v-if="isDateTime" prop="dateTimePattern">
            <el-input v-model="fieldOfBean.dateTimePattern" minlength="1" maxlength="40"/>
          </el-form-item>
          <el-form-item label="显示在列表" prop="showOnTable">
            <el-switch v-model="fieldOfBean.showOnTable"/>
          </el-form-item>
        </el-form>
      </el-col>
    </el-row>
    <div slot="footer">
      <el-button type="primary" :disabled="invalid" @click="confirm()">确定</el-button>
      <el-button @click="cancel()">取消</el-button>
    </div>
  </el-dialog>
</template>

<script>
import elementLayout from '../plugins/element/layout.js';
import elementForm from '../plugins/element/form.js';
import elementInput from '../plugins/element/input.js';
import elementInputNumber from '../plugins/element/input_number.js';
import elementSelect from '../plugins/element/select.js';
import elementSwitch from '../plugins/element/switch.js';
import elementButton from '../plugins/element/button.js';

import { validateNotBlank, validateSQLIdentifier, validatePositiveJavaScriptInteger }
    from "../plugins/element/validators.js";

const component = {
  name: "field_edit",
  props: {
    index: Number,
    beanName: String,
    field: {
      validator(value) {
        if (typeof(value) !== "object") {
          return false;
        }
        if (value === null) {
          return true;
        }
        if (typeof(value.id) !== "string" || typeof(value.name) !== "string" ||
            typeof(value.dbColumn) !== "string" || typeof(value.dataType) !== "string") {
          return false;
        }
        return true;
      }
    }
  },
  data() {
    return {
      fieldOfBean: {
        id: "",
        name: "",
        dataType: "VARCHAR",
        dbColumn: "",
        precisionOrLength: null,
        dateTimePattern: null,
        showOnTable: false
      },
      isFieldValid: {
        name: false,
        dbColumn: false,
        precisionOrLength: true,
        dateTimePattern: true
      },
      rules: {
        name: [
          { validator: validateNotBlank, message: "请输入字段名称", trigger: "change" },
          { max: 40, message: "字段名称最多 40 个字符", trigger: "change" }
        ],
        dbColumn: [
          { validator: validateNotBlank, message: "请输入数据库表的列名", trigger: "change" },
          { max: 40, message: "数据库表的列名最多 40 个字符", trigger: "change" },
          { validator: validateSQLIdentifier, trigger: "change" }
        ],
        precisionOrLength: [
          { validator: validatePositiveJavaScriptInteger, trigger: "change" }
        ]
      }
    };
  },
  computed: {
    isVisible() {
      return typeof(this.index) === "number" && /^\d{1,10}$/.test("" + this.index);
    },
    isUpdate() {
      return !!this.fieldOfBean.id;
    },
    header() {
      return (this.isUpdate ? "编辑" : "添加") +
          (this.beanName ? ("“" + this.beanName + "”的") : "") + "字段";
    },
    precisionOrLengthLabel() {
      switch (this.fieldOfBean.dataType) {
        case "VARCHAR":
          return "长度";
        case "DECIMAL":
          return "精度（位数）";
      }
      return "";
    },
    isDateTime() {
      return this.fieldOfBean.dataType === "DATETIME" || this.fieldOfBean.dataType === "DATE" ||
          this.fieldOfBean.dataType === "TIME";
    },
    invalid() {
      return !this.isFieldValid.name || !this.isFieldValid.dbColumn ||
          (!!this.precisionOrLengthLabel && !this.isFieldValid.precisionOrLength);
    }
  },
  watch: {
    isVisible(value) {
      if (!value) {
        return;
      }
      this.fieldOfBean.id = this.field.id;
      this.fieldOfBean.name = this.field.name;
      this.fieldOfBean.dbColumn = this.field.dbColumn;
      this.fieldOfBean.dataType = this.field.dataType;
      this.fieldOfBean.precisionOrLength = this.field.precisionOrLength;
      this.fieldOfBean.dateTimePattern = this.field.dateTimePattern;
      this.fieldOfBean.showOnTable = this.field.showOnTable === 1;
      this.isFieldValid = {
        name: true,
        dbColumn: true,
        precisionOrLength: true,
        dateTimePattern: true
      }
    },
    precisionOrLengthLabel(value) {
      if (!value) {
        this.fieldOfBean.precisionOrLength = null;
      } else { // value is not null
        if (!this.fieldOfBean.precisionOrLength) {
          this.fieldOfBean.precisionOrLength = 10;
        }
      }
    },
    isDateTime(value) {
      if (!value) {
        this.fieldOfBean.dateTimePattern = null;
      }
    }
  },
  methods: {
    formValidated(prop, valid) {
      this.isFieldValid[prop] = valid;
    },
    confirm() {
      this.$refs.fieldForm.validate((isValid) => {
        if (!isValid) {
          return;
        }
        this.$emit("submit", {
          index: this.index,
          id: this.fieldOfBean.id,
          name: this.fieldOfBean.name,
          dataType: this.fieldOfBean.dataType,
          dbColumn: this.fieldOfBean.dbColumn,
          precisionOrLength: this.fieldOfBean.precisionOrLength,
          dateTimePattern: this.fieldOfBean.dateTimePattern,
          showOnTable: this.fieldOfBean.showOnTable ? 1 : 0
        });
      });
    },
    cancel() {
      this.$emit("submit", null);
    }
  }
};

elementLayout(component);
elementForm(component);
elementInput(component);
elementInputNumber(component);
elementSelect(component);
elementSwitch(component);
elementButton(component);

export default component;
</script>
